(load "object.el")

(defun Number (name)
  (let* ((*class "Number")
	 (*instance-name name)
	 (*value nil)
	 (*super (Object name))
	 
	 (*dispatch
	  (lambda (msg)
	    (cond ((eq msg "value")
		   (lambda () *value))
		  ((or (eq msg "name")(eq msg "instance-name"))
		   (lambda () *instance-name))
		  ((eq msg "+")
		   (lambda (aNumber) 
		     (+ *value ((aNumber "value")))))
		  ((eq msg "-")
		   (lambda (aNumber) 
		     (- *value ((aNumber "value")))))
		  ((eq msg "*")
		   (lambda (aNumber) 
		     (* *value ((aNumber "value")))));;FIXME
		  ((eq msg "/")
		   (lambda (aNumber)
		     (/ *value ((aNumber "value")))))
		  ((eq msg "abs")
		   (lambda ()
		     (abs *value)))
		  ((eq msg "negated")
		   (lambda ()
		     (- *value)))
		  ((or (eq msg "quo:") (eq msg "//"))
		   (lambda (aNumber)
		     (quotient *value ((aNumber "value")))))
		  ((or (eq msg "rem:") (eq msg "\\"))
		   (lambda (aNumber)
		     (remainder *value ((aNumber "value")))))
		  ((eq msg "reciprocal")
		   (lambda ()
		     (/ 1 *value)))
		  ((eq msg "exp")
		   (lambda ()
		     (exp *value)))
		  ((eq msg "ln")
		   (lambda ()
		     (log *value)))
;;		  ((eq msg "log:")
;;		   (lambda (aNumber)
;;		     (...)))
		  ((eq msg "raisedTo:")
		   (lambda (aNumber)
		     (exp *value ((aNumber "value")))))
		  ((eq msg "sqrt")
		   (lambda ()
		     (sqrt *value)))
		  ((eq msg "squared")
		   (lambda ()
		     (* *value *value)))

		  ((eq msg "even")
		   (lambda ()
		     (= (abs (/ *value 2))(/ *value 2))))
		  ((eq msg "odd")
		   (lambda ()
		     (not (= (abs (/ *value 2))(/ *value 2)))))
		  ((eq msg "negative")
		   (lambda ()
		     (not (= (abs *value)*value))))
		  ((eq msg "positive")
		   (lambda ()
		     (= (abs *value)*value)))
		  ((eq msg "strictlyPositive")
		   (lambda ()
		     (and (not (= *value 0))
			  (= (abs *value)*value))))
		  ((eq msg "sign")
		   (lambda ()
		     (cond ((< *value)
			    -1)
			   ((> *value)
			    1)
			   (else 0))))
		  ((eq msg "ceiling")
		   (lambda ()
		     (ceiling *value)))
		  ((eq msg "floor")
		   (lambda ()
		     (floor *value)))
		  ((eq msg "truncated")
		   (lambda ()
		     (truncate *value)))
		  ((eq msg "degreesToRadians")
		   (lambda ()
		     (* (/ 180 3.14152829) *value)))
		  ((eq msg "radiansToDegrees")
		   (lambda ()
		     (* (/ 3.14152829 180) *value)))
		  ((eq msg "sin")
		   (lambda ()
		     (sin *value)))
		  ((eq msg "cos")
		   (lambda ()
		     (cos *value)))
		  ((eq msg "tan")
		   (lambda ()
		     (tan *value)))
		  ((eq msg "arcSin")
		   (lambda ()
		     (arcsin *value)))
		  ((eq msg "arcTan")
		   (lambda ()
		     (arctan *value)))

		  (t
		   ((*super msg)))
		  )))
	 )
	 
    *dispatch))